<?php
/*
 * webuser.class.inc.php
 * MODx: web user API
 * Provides interaction with the modx user system.
 */

// Include the config file.
include_once('config.inc.php');
include_once('notify.class.inc.php');

class WebUser {

	// Set class variables.

	// Full table names
	var $table = array();
	// Allowable fields
	var $allowed_fields = array();

	var $error_info = '';

	// Initialize the class
	function __construct() {
		global $modx;

		$this->table['web_users'] = $modx->getFullTableName('web_users');
		$this->table['web_user_attributes'] = $modx->getFullTableName('web_user_attributes');
		$this->table['web_groups'] = $modx->getFullTableName('web_groups');

		// List out all valid fields for each table.
		// 'Required' fields cannot be blank on edit.
		// Also defined whether the field is 'Editable'.
		$this->allowed_fields['web_users'] = array(
			'id'				=> array('R' => 1, 'E' => 0),
			'username'			=> array('R' => 1, 'E' => 1),
			'password'			=> array('R' => 1, 'E' => 1),
			'cachepwd'			=> array('R' => 0, 'E' => 1),
		);

		// Note: this is not a complete list.
		$this->allowed_fields['web_user_attributes'] = array(
			'id'				=> array('R' => 1, 'E' => 0),
			'internalKey'		=> array('R' => 1, 'E' => 1),
			'fullname'			=> array('R' => 1, 'E' => 1),
			'role'				=> array('R' => 1, 'E' => 1),
			'email'				=> array('R' => 1, 'E' => 1),
			'phone'				=> array('R' => 0, 'E' => 1),
			'mobilephone'		=> array('R' => 0, 'E' => 1),
			'dob'				=> array('R' => 0, 'E' => 1),
			'gender'			=> array('R' => 0, 'E' => 1),
			'country'			=> array('R' => 0, 'E' => 1),
			'state'				=> array('R' => 0, 'E' => 1),
			'zip'				=> array('R' => 0, 'E' => 1),
			'fax'				=> array('R' => 0, 'E' => 1),
			'photo'				=> array('R' => 0, 'E' => 1),
			'comment'			=> array('R' => 0, 'E' => 1),
		);
		
		$this->allowed_fields['web_groups'] = array(
			'id'				=> array('R' => 1, 'E' => 0),
			'webgroup'			=> array('R' => 1, 'E' => 1),
			'webuser'			=> array('R' => 1, 'E' => 1),
		);
	}

	// Add a modx webuser based on a customer.
	function addWebUser($add_spec=array()) {
		global $modx, $DEFAULT_WEB_USER_GROUP_ID;

		//print 'Got the following spec in addWebUser: ' . print_r($add_spec, true) . "\ndone\n\n";

		// Sanitize the spec.
		$username_spec = $this->sanitizeAddSpec('web_users', $add_spec);

		// Check if this username is unique.
		$sql = "SELECT COUNT(id) AS `exists` FROM ".$this->table['web_users']." WHERE `username` = '".$username_spec['username']."'";
		if (intval($modx->db->getValue($sql)) > 0) {
			$this->error_info = 'This username already exists: '.$username_spec['username'];
			return NULL;
		}

		// Add the user.
		$web_user_id = $modx->db->insert($username_spec, $this->table['web_users']);
		if (!$web_user_id) {
			$this->error_info = 'Error while adding the web user.';
			return NULL;
		}

		// Add the web_user_id to the attribute spec so it gets referenced properly.
		$add_spec['internalKey'] = $web_user_id;

		// Prepare the attributes.
		$attribute_spec = $this->sanitizeAddSpec('web_user_attributes', $add_spec);

		// Add the attributes.
		$web_user_attribute_id = $modx->db->insert($attribute_spec, $this->table['web_user_attributes']);

		if ($DEFAULT_WEB_USER_GROUP_ID > 0) {
			// Add the new user to this group.
			if (!$group_id = $this->addWebUserGroup($web_user_id, $DEFAULT_WEB_USER_GROUP_ID)) {
				$this->error_info = 'Error while adding the web user to their group.';
				return NULL;
			}
		}

		return $web_user_id;
	}
	// end of addWebUser

	// Edit a modx webuser based on a customer.
	function editWebUser($web_user_id, $edit_spec=array()) {
		global $modx, $DEFAULT_WEB_USER_GROUP_ID;
		
		//print 'Got the following spec in editWebUser: ' . print_r($edit_spec, true) . "\ndone\n\n";

		// Check if this username is unique (in case it changed).
		$sql = "SELECT COUNT(id) AS `exists` FROM ".$this->table['web_users']." WHERE `username` = '".$edit_spec['username']."' AND `id` != '$web_user_id'";
		if (intval($modx->db->getValue($sql)) > 0) {
			$this->error_info = 'This username already exists: '.$edit_spec['username'];
			return NULL;
		}

		$username_spec = $this->sanitizeEditSpec('web_users', $edit_spec);
		
		if (count($username_spec) > 0) {
			// Edit the user.
			$edit_id = $modx->db->update($username_spec, $this->table['web_users'], "`id` = '$web_user_id'");
			if (!$edit_id) {
				$this->error_info = 'Error while editing the web user.';
				return NULL;
			}
		}

		// Edit the attributes.
		$attribute_spec = $this->sanitizeEditSpec('web_user_attributes', $edit_spec);

		if (count($attribute_spec) > 0) {
			$web_user_attribute_id = $modx->db->update($attribute_spec, $this->table['web_user_attributes'], "`internalKey` = '$web_user_id'");
			if (!$web_user_attribute_id) {
				$this->error_info = 'Error while editing the web user attributes.';
				return NULL;
			}
		}

		return $web_user_id;
	}
	// end of editWebUser

	// Add a web user to a group.
	function addWebUserGroup($web_user_id, $group_id) {
		global $modx;

		$group_spec = array(
			'webgroup' => $group_id,
			'webuser' => $web_user_id,
		);
		$group_id = $modx->db->insert($group_spec, $this->table['web_groups']);
		if (!$group_id) {
			$this->error_info = 'Error while adding the web user to their group.';
			return NULL;
		}

		return $group_id;
	}
		
	// Prepare a spec for sql insertion by removing any nonexistent fields. 
	// Db escape each value as well.
	function sanitizeAddSpec ($table_name, $add_spec=array()) {
		global $modx;
		// Verify the fields to add.
		foreach ($add_spec as $key => $value) {
			if ( !array_key_exists($key, $this->allowed_fields[$table_name])
				|| $this->allowed_fields[$table_name][$key]['R'] == 1 && $value == '' )
			{
				// Remove this field.
				unset($add_spec[$key]);
			}
			else {
				// Escape for the db.
				$add_spec[$key] = $modx->db->escape($value);
			}
		}

		// Return the sanitized spec.
		return $add_spec;
	}

	// Prepare a spec for sql update by removing any non-editable fields.
	// Required fields with no value are also removed.
	// Db escape each value as well.
	function sanitizeEditSpec ($table_name, $edit_spec=array(), $skip_escape=FALSE) {
		global $modx;
		// Verify the fields to edit.
		foreach ($edit_spec as $key => $value) {
			if ( !array_key_exists($key, $this->allowed_fields[$table_name])
				|| $this->allowed_fields[$table_name][$key]['E'] == 0 
				|| $this->allowed_fields[$table_name][$key]['R'] == 1 && $value == ''
			)
			{
				// Remove this field.
				unset($edit_spec[$key]);
			}
			elseif (!$skip_escape) {
				// Escape for the db.
				$edit_spec[$key] = $modx->db->escape($value);
			}
		}

		// Return the sanitized spec.
		return $edit_spec;
	}

} // end class

?>
